/**$6
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 *
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 */

#ifndef __RS485O_H__
#define __RS485O_H__
#include <Config.h>
#include <stdlib.h>
#include <string.h>
enum rxState
{
	WAIT_START,
	WAIT_ADDR_HIGH,
	WAIT_ADDR_LOW,
	CMD,
	WAIT_LEN,
	WAIT_DATA,
	WAIT_CRC_HIGH,
	WAIT_CRC_LOW,
	COMPLETE,
	VALID,
	INVALID			= 255
};
typedef enum rxState rxState;
enum errState { BAD_LENGTH = 0x01, BAD_CRC = 0x02, OK_CRC = 0x04 };
typedef enum errState	errState;

/**
 -----------------------------------------------------------------------------------------------------------------------
 * Structure with communication variable ;
 * used for sending /receiving packet ;
 * Here only variable that are not phisically sent over the line
 -----------------------------------------------------------------------------------------------------------------------
 */
typedef struct CommProt
{
	WORD	cOurAddr;		/* Our address */

	/*
	 * char cRs485RxChar;
	 * /* last received char
	 */
	rxState cRS485State;	/* state of receiveing */
	WORD	cCalcCrc;		/* Our Calculated Crc byte */
	char	cBufPtr;		/* Pointer in Buffer */
	char	cError;			/* Packet Error */
	BOOL	isPacketForMe;
	int		nrOkRxPacketForMe;
	int		nrOkRxPacketForOther;
	int		nrWrongPacket;
	int		nrSerialError;
} CommProt;
typedef struct RxPacket
{
	WORD	cStart;			/* Start char of message */
	WORD	cNetAddr;
	char	cLenExpected;	/* Expected length of message */
	char	cCommand;		/* Received Command */
	char	*c485Buf;		/* Data Buffer of cLenExpected length */
	WORD	cRxCrc;			/* Actual received CRC byte */
} RxPacket;
typedef struct TxPacket
{
	char	cStart;
	WORD	cNetAddr;
	char	cLenExpected;
	char	cCommand;
	char	c485Buf[64];
	WORD	cCalcCrc;
} TxPacket;
enum Rs485Flag { SER_RX = 0x01, SER_TX = 0x02, SER_ERR = 0x04 };
extern unsigned char		*strPacket;
extern OST_MSG	drv_rs485_msg_rx;
extern OST_MSG	drv_rs485_msg_tx;
extern OST_MSG	drv_rs485_smsg_char;
extern OST_QUEUE	DRV_rs485_qmsg_rx;
extern OST_QUEUE	DRV_rs485_qmsg_tx;
extern OST_SQUEUE	DRV_rs485_q_char;
extern OST_SMSG		DRV_rs485_smsg_q_char[RS485_SIZEOF_CBUF];
extern OST_MSG	DRV_rs485_msg_q_tx[RS485_SIZEOF_MSGQ];
extern OST_MSG	DRV_rs485_msg_q_rx[RS485_SIZEOF_MSGQ];
extern OST_FLAG		Rs485Flag;

extern void Rs485Initialise(WORD);

/*
 * extern char Rs485Decode(RxPacket *, CommProt *, char);
 */
extern void Rs485UpdateCrc(char cVal);
extern void CRC16_Init(void);
extern void CRC16_Update4Bits(char val);
extern void Rs485SendPacket(TxPacket *);
extern void Rs485SendChar(char c);
extern char PostValidatePacket(RxPacket *commprt);
extern BOOL PacketHasPayload(void);
extern void BinToHexAscii(char c);
extern char *MakeStr(char *cData, char cLen, char cCmd);
extern int	Rs485BuildPacket(unsigned char *str, TxPacket *txPacket);
#define NUM_TX_PREAMBLE 3
#define MAX_DATA_LENGTH 64	/* max nr of data char in packet */

/* Protocol defines */
#define PKT_START	0x02


#if defined(__DEBUG)
extern RxPacket *rxPacket;
extern CommProt *commProt;
#endif


/*
 * FIXME Da sostituire con Enum ;
 * States of packet decoder state machine ;
 * Packet types
 */
#define SENSOR_POLL_CMD		0xA1
#define SENSOR_PING_SYNC	0xA2
#define SENSOR_CONFIG		0xA3
#define SENSOR_GET_DATA		0xA4
#define SENSOR_ACK			0xB0
#define SENSOR_NAK			0xC0
#endif
